from typing import Union, Dict, Any

import ujson
from fastapi import Request, Query
from pydantic import BaseModel


def get_mgw(request: Request):
    return request.app.mgw


def get_redis(request: Request):
    return request.app.redis


def get_current_user_id(request: Request):
    if hasattr(request.state, "user_id"):
        return request.state.user_id
    return None


def get_settings(request: Request):
    return request.app.settings


def get_tenant_id(request: Request):
    if hasattr(request.state, "tenant_id"):
        return request.state.tenant_id
    return None


def get_mall_id(request: Request):
    if hasattr(request.state, "mall_id"):
        return request.state.mall_id
    return None


class Page(BaseModel):
    page: int
    page_size: int


def get_page_info(page: int = Query(1, description="页码"), page_size: int = Query(10, description="每页数据量")) -> Page:
    return Page(page=page, page_size=page_size)


async def get_current_tenant(request: Request) -> Union[None, Dict[str, Any]]:
    from service.tenant_service import TenantService
    from common.g.g import G_REDIS
    mgw = get_mgw(request)
    ts = TenantService(mgw, G_REDIS)
    tenant_id = get_tenant_id(request)
    ok, tenant = await ts.get_tenant_by_tenant_id(tenant_id)
    if ok:
        return tenant.data
    return None


async def get_current_user(request: Request):
    from common.g.g import G_REDIS
    from service.tenant_service import TenantUserService

    current_user_id = get_current_user_id(request)
    cache_data = await G_REDIS.get(f"user:detail:{current_user_id}")
    if cache_data:
        return ujson.loads(cache_data)
    tus = TenantUserService(request.app.mgw, G_REDIS)
    data = await tus.get_user_info_by_condition(user_id=current_user_id)
    return data


def get_request_id(request: Request) -> str:
    return request.state.request_id


async def get_tenant_config(request: Request):
    from common.g.g import G_REDIS
    from service.tenant_service import TenantConfigService

    mgw = get_mgw(request)
    tcs = TenantConfigService(mgw, G_REDIS)
    ok, data_or_code = await tcs.get_config(tenant_id=request.state.tenant_id)
    if not ok:
        return {}
    return data_or_code.data


